package com.cs.sso.service.impl;

import com.cs.sso.dbo.Account;
import com.cs.sso.exception.LoginException;
import com.cs.sso.service.AccountService;
import com.cs.sso.service.LoginLogService;
import com.cs.sso.service.LoginService;
import com.cs.sso.service.TokenService;
import com.cs.sso.vo.LoginToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class LoginServiceImpl implements LoginService {
    @Autowired
    private AccountService accountService;

    @Autowired
    private LoginLogService loginLogService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private int expireTime = 60 * 24 * 7; // token一周过期
    private int maxErrorTimes = 6; // 最大密码错误次数

    @Override
    public LoginToken login(String username, String password) throws LoginException {
        // 检查登录密码正确性
        Account account = accountService.findUser(username);
        if ("LOCK".equals(account.getStatus())) {
            throw new LoginException("账号已锁定");
        }
        if ("DENY".equals(account.getStatus())) {
            throw new LoginException("账号已作废");
        }

        // 记录登录日志
        if (!password.equals(account.getPassword())) {
            loginLogService.writeErrorLog(username);
            // 密码错误次数超限，锁定账号
            int errorTimes = loginLogService.currentErrorTimes(username);
            log.info("{}密码错误次数:{}", username, errorTimes);
            if (errorTimes >= maxErrorTimes) {
                log.info("{}密码错误次数超过限制，账号锁定", username);
                accountService.lockUser(username);
            }
            throw new LoginException("密码错误");
        }
        loginLogService.writeSuccessLog(username);

        // 产生token
        String token = tokenService.getToken();

        // 写入redis
        LoginToken loginToken = new LoginToken();
        BeanUtils.copyProperties(account, loginToken);
        loginToken.setToken(token);
        log.info("loginToken:{}", loginToken);
        String tokenString = loginToken.getUsername() + "|" + loginToken.getName();
        log.info("tokenString:{}", tokenString);
        stringRedisTemplate.opsForValue().set(token, tokenString, expireTime, TimeUnit.MINUTES);

        return loginToken;
    }
}
